﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.IO;
using Mercury.Core.Const;
using Mercury.Core.Extensions;
using System.Collections.Generic;
using Mercury.Core.DBManager;
using Mercury.Entity.DomainModels.System;
using System;
using Mercury.Entity.DomainModels;
using Mercury.Entity.SystemModels;
using System.Linq;

namespace Mercury.Core.Configuration
{
    public static class AppSetting
    {
        public static IConfiguration Configuration { get; private set; }

        public static string DbConnectionString
        {
            get { return _connection.DbConnectionString; }
        }

        public static string RedisConnectionString
        {
            get { return _connection.RedisConnectionString; }
        }

        public static bool UseRedis
        {
            get { return _connection.UseRedis; }
        }
        public static bool UseSignalR
        {
            get { return _connection.UseSignalR; }
        }
        public static Secret Secret { get; private set; }

        public static CreateMember CreateMember { get; private set; }

        public static ModifyMember ModifyMember { get; private set; }

        private static Connection _connection;

        public static string TokenHeaderName = "Authorization";

        /// <summary>
        /// Actions权限过滤
        /// </summary>
        public static GlobalFilter GlobalFilter { get; set; }

        /// <summary>
        /// kafka配置
        /// </summary>
        public static Kafka Kafka { get; set; }

        public static bool SoftDeletion { get; private set; }

        public static string DeletionFlagField { get; private set; }


        public static Sys_LogConfig LogConfig { get; set; }

        private static List<Sys_Config> _config { get; set; }

        public static string GetConfig(this string key)
        {
            return _config.FirstOrDefault(c => c.Name == key)?.Value.ToString();
        }

        public static List<NoticeConfig> NoticeConfigs { get; set; }

        /// <summary>
        /// JWT有效期(分钟=默认120)
        /// </summary>
        public static int ExpMinutes { get; private set; } = 120;

        /// <summary>
        /// 领料单计算上浮比例
        /// </summary>
        public static double Rate { get; private set; } = 1.0;

        /// <summary>
        /// 是否启用物料元素所得率
        /// </summary>
        public static bool EnableMaterialElementYieldRate { get; set; } = true;

        public static string CurrentPath { get; private set; } = null;
        public static string DownLoadPath { get { return CurrentPath + "\\Download\\"; } }
        public static void Init(IServiceCollection services, IConfiguration configuration)
        {
            Configuration = configuration;
            services.Configure<Secret>(configuration.GetSection("Secret"));
            services.Configure<Connection>(configuration.GetSection("Connection"));
            services.Configure<CreateMember>(configuration.GetSection("CreateMember"));
            services.Configure<ModifyMember>(configuration.GetSection("ModifyMember"));
            services.Configure<GlobalFilter>(configuration.GetSection("GlobalFilter"));
            services.Configure<Kafka>(configuration.GetSection("Kafka"));
            services.Configure<Deletion>(configuration.GetSection("Deletion"));
            services.Configure<Replenishment>(configuration.GetSection("Replenishment"));

            var provider = services.BuildServiceProvider();
            IWebHostEnvironment environment = provider.GetRequiredService<IWebHostEnvironment>();
            CurrentPath = Path.Combine(environment.ContentRootPath, "").ReplacePath();

            Secret = provider.GetRequiredService<IOptions<Secret>>().Value;

            //设置修改或删除时需要设置为默认用户信息的字段
            CreateMember = provider.GetRequiredService<IOptions<CreateMember>>().Value ?? new CreateMember();
            ModifyMember = provider.GetRequiredService<IOptions<ModifyMember>>().Value ?? new ModifyMember();

            GlobalFilter = provider.GetRequiredService<IOptions<GlobalFilter>>().Value ?? new GlobalFilter();

            GlobalFilter.Actions = GlobalFilter.Actions ?? new string[0];
            Kafka = provider.GetRequiredService<IOptions<Kafka>>().Value ?? new Kafka();

            var deletion = provider.GetRequiredService<IOptions<Deletion>>().Value ?? new Deletion();
            DeletionFlagField = deletion.DeletionFlagField;
            SoftDeletion = !string.IsNullOrEmpty(DeletionFlagField) && deletion.SoftDeletion;
            _connection = provider.GetRequiredService<IOptions<Connection>>().Value;

            Replenishment = provider.GetRequiredService<IOptions<Replenishment>>().Value ?? new Replenishment();
            if (Replenishment.LowerRate < 0 || Replenishment.LowerRate > 100)
                Replenishment.LowerRate = 100;

            if (Replenishment.UpperRate < 0 || Replenishment.UpperRate > 100)
                Replenishment.UpperRate = 100;

            SystemUser.Enable = (configuration["EnableSystem"] ?? "true").GetBool();
            ExpMinutes = (configuration["ExpMinutes"] ?? "120").GetInt();
            Rate = (configuration["Rate"] ?? "100").GetDouble() / 100;

            DBType.Name = _connection.DBType;
            if (string.IsNullOrEmpty(_connection.DbConnectionString))
                throw new System.Exception("未配置好数据库默认连接");

            try
            {
                _connection.DbConnectionString = _connection.DbConnectionString.DecryptDES(Secret.DB);
                LogConfig = DBServerProvider.SqlDapper.QueryFirst<Sys_LogConfig>("Select * From Sys_LogConfig", null);
                _config = DBServerProvider.SqlDapper.QueryList<Sys_Config>("SELECT * FROM dbo.Sys_Config WHERE Enable = 1", null);
                if (UseSignalR)
                    NoticeConfigs = DBServerProvider.SqlDapper.QueryList<NoticeConfig>("SELECT * FROM NoticeConfig WHERE ISNULL(DeletionFlag,0) = 0 ", null);
            }
            catch { }

            if (!string.IsNullOrEmpty(_connection.RedisConnectionString))
            {
                try
                {
                    _connection.RedisConnectionString = _connection.RedisConnectionString.DecryptDES(Secret.Redis);
                }
                catch { }
            }

        }
        // 多个节点name格式 ：["key:key1"]
        public static string GetSettingString(string key)
        {
            return Configuration[key];
        }
        // 多个节点,通过.GetSection("key")["key1"]获取
        public static IConfigurationSection GetSection(string key)
        {
            return Configuration.GetSection(key);
        }

        public static Replenishment Replenishment { get; set; }
    }

    public class Connection
    {
        public string DBType { get; set; }
        public string DbConnectionString { get; set; }
        public string RedisConnectionString { get; set; }
        public bool UseRedis { get; set; }
        public bool UseSignalR { get; set; }
    }

    public class Replenishment
    {
        public int LowerRate { get; set; }

        public int UpperRate { get; set; }
    }
    public class CreateMember : TableDefaultColumns
    {
    }
    public class ModifyMember : TableDefaultColumns
    {
    }

    public abstract class TableDefaultColumns
    {
        public List<string> UserIdField { get; set; }
        public List<string> UserNameField { get; set; }
        public List<string> DateField { get; set; }
    }
    public class GlobalFilter
    {
        public string Message { get; set; }
        public bool Enable { get; set; }
        public string[] Actions { get; set; }
    }

    public class Kafka
    {
        public bool UseProducer { get; set; }
        public ProducerSettings ProducerSettings { get; set; }
        public bool UseConsumer { get; set; }
        public bool IsConsumerSubscribe { get; set; }
        public ConsumerSettings ConsumerSettings { get; set; }
        public Topics Topics { get; set; }
    }
    public class ProducerSettings
    {
        public string BootstrapServers { get; set; }
        public string SaslMechanism { get; set; }
        public string SecurityProtocol { get; set; }
        public string SaslUsername { get; set; }
        public string SaslPassword { get; set; }
    }
    public class ConsumerSettings
    {
        public string BootstrapServers { get; set; }
        public string SaslMechanism { get; set; }
        public string SecurityProtocol { get; set; }
        public string SaslUsername { get; set; }
        public string SaslPassword { get; set; }
        public string GroupId { get; set; }
    }
    public class Topics
    {
        public string TestTopic { get; set; }
    }

    /// <summary>
    /// 删除配置项
    /// </summary>

    public class Deletion
    {
        /// <summary>
        /// 软删除
        /// </summary>
        public bool SoftDeletion { get; set; }

        /// <summary>
        /// 软删除配置字段
        /// </summary>
        public string DeletionFlagField { get; set; }
    }

    public class SystemUser
    {
        public static Sys_User Instance { get; } = new Sys_User()
        {
            UserName = "DTServer",
            Salt = "3e61b6449bd79dc078fe749ae4ce97b9",
            UserPwd = "PEdQasO6Nr4qBfxywlETIAGDueD9gij8MNeBRlloG2LeiIA2nTYl88FV1EG34lQR",
            Enable = 1,
            Role_Id = 1,
            User_Id = -999,
            UserTrueName = "DT"
        };

        public static bool Enable = true;
    }
}
